package view.student;

import controller.ReservationController;
import controller.SystemSettingsController;
import model.User;
import model.Reservation;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Comparator;
import java.util.List;

/**
 * 我的预约面板
 */
public class MyReservationsPanel extends JPanel {
    private User currentUser;
    private ReservationController reservationController;
    private SystemSettingsController systemSettingsController;

    private JTable reservationTable;
    private DefaultTableModel tableModel;
    private TableRowSorter<DefaultTableModel> tableSorter;
    private JButton cancelButton;
    private JButton refreshButton;

    public MyReservationsPanel(User user) {
        this.currentUser = user;
        this.reservationController = new ReservationController();
        this.systemSettingsController = new SystemSettingsController();

        initComponents();
        setupLayout();
        setupEventListeners();
        refreshData();
    }

    private void initComponents() {
        setLayout(new BorderLayout());
        setBackground(new Color(248, 250, 252));

        // 表格列名
        String[] columnNames = { "预约ID", "座位号", "楼层", "预约日期", "开始时间", "结束时间", "状态", "预约时间" };
        tableModel = new DefaultTableModel(columnNames, 0) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return false; // 表格不可编辑
            }
        };

        reservationTable = new JTable(tableModel);
        reservationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        reservationTable.setRowHeight(30);

        // 添加排序功能
        tableSorter = new TableRowSorter<>(tableModel);
        reservationTable.setRowSorter(tableSorter);

        // 配置表头样式
        JTableHeader header = reservationTable.getTableHeader();
        header.setFont(new Font("Microsoft YaHei", Font.BOLD, 12));
        header.setBackground(new Color(243, 244, 246));
        header.setForeground(new Color(75, 85, 99));
        header.setReorderingAllowed(false);

        // 美化表格
        styleTable(reservationTable);

        // 简化排序配置，让系统自动处理
        // setupColumnComparators();

        // 设置列宽
        reservationTable.getColumnModel().getColumn(0).setPreferredWidth(80);
        reservationTable.getColumnModel().getColumn(1).setPreferredWidth(80);
        reservationTable.getColumnModel().getColumn(2).setPreferredWidth(60);
        reservationTable.getColumnModel().getColumn(3).setPreferredWidth(100);
        reservationTable.getColumnModel().getColumn(4).setPreferredWidth(80);
        reservationTable.getColumnModel().getColumn(5).setPreferredWidth(80);
        reservationTable.getColumnModel().getColumn(6).setPreferredWidth(80);
        reservationTable.getColumnModel().getColumn(7).setPreferredWidth(120);

        cancelButton = new JButton("取消预约");
        refreshButton = new JButton("刷新");

        // 美化按钮 - 使用统一的现代化样式
        styleModernButton(cancelButton, new Color(239, 68, 68));
        styleModernButton(refreshButton, new Color(99, 102, 241));

        cancelButton.setEnabled(false);
    }

    private void setupLayout() {
        // 现代化顶部工具栏
        JPanel toolPanel = new JPanel(new BorderLayout());
        toolPanel.setBackground(new Color(255, 255, 255));
        toolPanel.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createLineBorder(new Color(229, 231, 235), 1),
                BorderFactory.createEmptyBorder(20, 20, 20, 20)));

        // 左侧标题和说明
        JPanel leftPanel = new JPanel();
        leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));
        leftPanel.setBackground(new Color(255, 255, 255));

        JLabel titleLabel = new JLabel("我的预约记录");
        titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 20));
        titleLabel.setForeground(new Color(55, 65, 81));
        titleLabel.setAlignmentX(Component.LEFT_ALIGNMENT);

        JLabel descLabel = new JLabel("查看和管理您的所有座位预约记录");
        descLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
        descLabel.setForeground(new Color(107, 114, 128));
        descLabel.setAlignmentX(Component.LEFT_ALIGNMENT);

        // 重点提示
        JPanel tipPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5));
        tipPanel.setBackground(new Color(255, 255, 255));
        tipPanel.setAlignmentX(Component.LEFT_ALIGNMENT);

        JLabel tipIcon = new JLabel("💡");
        tipIcon.setFont(new Font("Segoe UI Emoji", Font.PLAIN, 16));

        String cancelDeadlineText = getCancelDeadlineText();
        JLabel tipLabel = new JLabel("【重点】" + cancelDeadlineText);
        tipLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 13));
        tipLabel.setForeground(new Color(185, 28, 28));

        tipPanel.add(tipIcon);
        tipPanel.add(Box.createHorizontalStrut(8));
        tipPanel.add(tipLabel);

        leftPanel.add(titleLabel);
        leftPanel.add(Box.createVerticalStrut(5));
        leftPanel.add(descLabel);
        leftPanel.add(Box.createVerticalStrut(8));
        leftPanel.add(tipPanel);

        // 右侧按钮区域
        JPanel rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
        rightPanel.setBackground(new Color(255, 255, 255));

        rightPanel.add(refreshButton);
        rightPanel.add(Box.createHorizontalStrut(10));
        rightPanel.add(cancelButton);

        toolPanel.add(leftPanel, BorderLayout.WEST);
        toolPanel.add(rightPanel, BorderLayout.EAST);

        // 现代化表格滚动面板
        JScrollPane scrollPane = new JScrollPane(reservationTable);
        scrollPane.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createLineBorder(new Color(229, 231, 235), 1),
                BorderFactory.createEmptyBorder(0, 0, 0, 0)));
        scrollPane.getViewport().setBackground(new Color(255, 255, 255));

        // 现代化底部统计信息
        JPanel infoPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        infoPanel.setBackground(new Color(255, 255, 255));
        infoPanel.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createMatteBorder(1, 0, 0, 0, new Color(229, 231, 235)),
                BorderFactory.createEmptyBorder(15, 20, 15, 20)));

        JLabel totalLabel = createStyledLabel("总预约次数: 0");
        JLabel activeLabel = createStyledLabel("有效预约: 0");
        JLabel canceledLabel = createStyledLabel("已取消: 0");

        infoPanel.add(totalLabel);
        infoPanel.add(Box.createHorizontalStrut(25));
        infoPanel.add(activeLabel);
        infoPanel.add(Box.createHorizontalStrut(25));
        infoPanel.add(canceledLabel);

        add(toolPanel, BorderLayout.NORTH);
        add(scrollPane, BorderLayout.CENTER);
        add(infoPanel, BorderLayout.SOUTH);
    }

    private void setupEventListeners() {
        refreshButton.addActionListener(_ -> refreshData());

        cancelButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                handleCancelReservation();
            }
        });

        // 表格选择事件
        reservationTable.getSelectionModel().addListSelectionListener(e -> {
            if (!e.getValueIsAdjusting()) {
                int selectedRow = reservationTable.getSelectedRow();
                if (selectedRow >= 0) {
                    String status = (String) tableModel.getValueAt(selectedRow, 6);
                    Object dateObj = tableModel.getValueAt(selectedRow, 3);
                    Object startTimeObj = tableModel.getValueAt(selectedRow, 4);

                    // 安全地转换为字符串
                    String reservationDate = dateObj != null ? dateObj.toString() : "";
                    String startTime = startTimeObj != null ? startTimeObj.toString() : "";

                    // 检查是否可以取消预约：需要检查系统设置和时间限制
                    boolean canCancel = canCancelReservationBySettings(status, reservationDate, startTime);
                    cancelButton.setEnabled(canCancel);

                    // 更新按钮文本提示
                    if ("有效".equals(status)) {
                        if (canCancel) {
                            cancelButton.setText("取消预约");
                            cancelButton.setToolTipText("可以取消此预约");
                        } else {
                            cancelButton.setText("无法取消");
                            String deadlineText = getCancelDeadlineText();
                            cancelButton.setToolTipText(deadlineText.replace("才可以", "，无法"));
                        }
                    } else {
                        cancelButton.setText("取消预约");
                        cancelButton.setToolTipText("此预约不可取消");
                    }
                } else {
                    cancelButton.setEnabled(false);
                    cancelButton.setText("取消预约");
                    cancelButton.setToolTipText("");
                }
            }
        });
    }

    public void refreshData() {
        try {
            List<Reservation> reservations = reservationController.getUserReservations(currentUser.getUserId());

            // 清空表格
            tableModel.setRowCount(0);

            // 填充数据
            for (Reservation reservation : reservations) {
                Object[] row = {
                        reservation.getReservationId(),
                        reservation.getSeat() != null ? reservation.getSeat().getSeatNumber() : "N/A",
                        reservation.getSeat() != null ? reservation.getSeat().getFloor() + "楼" : "N/A",
                        reservation.getReservationDate(),
                        reservation.getStartTime(),
                        reservation.getEndTime(),
                        reservation.getStatusText(),
                        reservation.getCreateTime().toString().substring(0, 16)
                };
                tableModel.addRow(row);
            }

            // 更新统计信息
            updateStatistics(reservations);

        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "加载预约记录失败: " + e.getMessage(),
                    "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void updateStatistics(List<Reservation> reservations) {
        int total = reservations.size();
        int active = 0;
        int canceled = 0;

        for (Reservation reservation : reservations) {
            switch (reservation.getStatus()) {
                case 0:
                    active++;
                    break;
                case 1:
                    canceled++;
                    break;
            }
        }

        // 更新标签文本（这里简化处理，实际应该获取组件引用）
        Component[] components = ((JPanel) getComponent(2)).getComponents();
        if (components.length >= 3) {
            ((JLabel) components[0]).setText("总预约次数: " + total);
            ((JLabel) components[2]).setText("有效预约: " + active);
            ((JLabel) components[4]).setText("已取消: " + canceled);
        }
    }

    private void handleCancelReservation() {
        int selectedRow = reservationTable.getSelectedRow();
        if (selectedRow < 0)
            return;

        int reservationId = (Integer) tableModel.getValueAt(selectedRow, 0);
        String seatNumber = (String) tableModel.getValueAt(selectedRow, 1);
        Object dateObj = tableModel.getValueAt(selectedRow, 3);
        Object startTimeObj = tableModel.getValueAt(selectedRow, 4);
        Object endTimeObj = tableModel.getValueAt(selectedRow, 5);

        // 安全地转换为字符串
        String reservationDate = dateObj != null ? dateObj.toString() : "";
        String startTime = startTimeObj != null ? startTimeObj.toString() : "";
        String endTime = endTimeObj != null ? endTimeObj.toString() : "";

        // 再次检查是否可以取消
        if (!canCancelReservationBySettings("有效", reservationDate, startTime)) {
            String deadlineText = getCancelDeadlineText();
            JOptionPane.showMessageDialog(this,
                    "此预约无法取消！\n" + deadlineText + "。",
                    "无法取消", JOptionPane.WARNING_MESSAGE);
            return;
        }

        // 构建确认对话框内容
        String message = String.format(
                "确定要取消以下预约吗？\n\n" +
                        "座位号：%s\n" +
                        "日期：%s\n" +
                        "时间：%s - %s\n\n" +
                        "注意：取消预约可能会影响您的信用分。",
                seatNumber, reservationDate, startTime, endTime);

        int option = JOptionPane.showConfirmDialog(this, message,
                "确认取消预约", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);

        if (option == JOptionPane.YES_OPTION) {
            try {
                boolean success = reservationController.cancelReservation(reservationId);
                if (success) {
                    JOptionPane.showMessageDialog(this,
                            "预约已成功取消！\n\n" +
                                    "座位号：" + seatNumber + "\n" +
                                    "日期：" + reservationDate + "\n" +
                                    "时间：" + startTime + " - " + endTime,
                            "取消成功", JOptionPane.INFORMATION_MESSAGE);
                    refreshData();
                } else {
                    JOptionPane.showMessageDialog(this,
                            "取消预约失败！\n请稍后重试或联系管理员。",
                            "取消失败", JOptionPane.ERROR_MESSAGE);
                }
            } catch (Exception e) {
                JOptionPane.showMessageDialog(this,
                        "取消预约失败：" + e.getMessage() + "\n\n" +
                                "请检查网络连接或联系管理员。",
                        "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    /**
     * 根据系统设置检查是否可以取消预约
     */
    private boolean canCancelReservationBySettings(String status, String reservationDate, String startTime) {
        try {
            // 检查系统是否允许取消预约
            var reservationSettings = systemSettingsController.getReservationSettings();
            if (!reservationSettings.isAllowCancelReservation()) {
                return false; // 系统不允许取消预约
            }

            // 只有有效预约才能取消
            if (!"有效".equals(status)) {
                return false;
            }

            // 解析预约日期和时间
            LocalDate date = LocalDate.parse(reservationDate);
            LocalTime time = LocalTime.parse(startTime);
            LocalDateTime reservationStart = LocalDateTime.of(date, time);

            // 获取当前时间
            LocalDateTime now = LocalDateTime.now();

            // 计算距离预约开始的时间差（小时）
            long hoursUntilStart = java.time.Duration.between(now, reservationStart).toHours();

            // 根据系统设置的取消截止时间判断
            return hoursUntilStart >= reservationSettings.getCancelDeadlineHours();

        } catch (Exception e) {
            // 解析失败或读取设置失败时默认不允许取消
            return false;
        }
    }

    /**
     * 获取取消预约的截止时间文本描述
     */
    private String getCancelDeadlineText() {
        try {
            var reservationSettings = systemSettingsController.getReservationSettings();
            if (!reservationSettings.isAllowCancelReservation()) {
                return "系统已禁用取消预约功能";
            }

            int hours = reservationSettings.getCancelDeadlineHours();
            if (hours == 1) {
                return "预约开始前1小时以上才可以取消预约";
            } else {
                return String.format("预约开始前%d小时以上才可以取消预约", hours);
            }
        } catch (Exception e) {
            // 如果读取设置失败，返回默认文本
            return "预约开始前1小时以上才可以取消预约";
        }
    }

    /**
     * 创建样式化标签
     */
    private JLabel createStyledLabel(String text) {
        JLabel label = new JLabel(text);
        label.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
        label.setForeground(new Color(75, 85, 99));
        return label;
    }

    /**
     * 美化表格样式
     */
    private void styleTable(JTable table) {
        table.setFont(new Font("Microsoft YaHei", Font.PLAIN, 13));
        table.setBackground(new Color(255, 255, 255));
        table.setForeground(new Color(55, 65, 81));
        table.setGridColor(new Color(229, 231, 235));
        table.setSelectionBackground(new Color(219, 234, 254));
        table.setSelectionForeground(new Color(30, 64, 175));

        // 表头样式
        table.getTableHeader().setFont(new Font("Microsoft YaHei", Font.BOLD, 13));
        table.getTableHeader().setBackground(new Color(249, 250, 251));
        table.getTableHeader().setForeground(new Color(55, 65, 81));
        table.getTableHeader().setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(229, 231, 235)));
    }

    /**
     * 现代化按钮样式（与统计页面一致）
     */
    private void styleModernButton(JButton button, Color backgroundColor) {
        // 根据按钮文字自动调整宽度
        int width = button.getText().equals("取消预约") || button.getText().equals("无法取消") ? 110 : 90;
        button.setPreferredSize(new Dimension(width, 38));
        button.setBackground(backgroundColor);
        button.setForeground(Color.WHITE);
        button.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
        button.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
        button.setFocusPainted(false);
        button.setCursor(new Cursor(Cursor.HAND_CURSOR));

        // 悬停效果
        button.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                if (button.isEnabled()) {
                    button.setBackground(backgroundColor.darker());
                }
            }

            @Override
            public void mouseExited(java.awt.event.MouseEvent evt) {
                if (button.isEnabled()) {
                    button.setBackground(backgroundColor);
                }
            }
        });
    }

    /**
     * 美化按钮样式（保留原有方法以备其他地方使用）
     */
    private void styleButton(JButton button, Color backgroundColor, Color textColor) {
        button.setPreferredSize(new Dimension(90, 32));
        button.setBackground(backgroundColor);
        button.setForeground(textColor);
        button.setFont(new Font("Microsoft YaHei", Font.PLAIN, 13));
        button.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createLineBorder(backgroundColor.darker(), 1),
                BorderFactory.createEmptyBorder(6, 12, 6, 12)));
        button.setFocusPainted(false);
        button.setCursor(new Cursor(Cursor.HAND_CURSOR));

        // 鼠标悬停效果
        button.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                if (button.isEnabled()) {
                    button.setBackground(backgroundColor.darker());
                }
            }

            @Override
            public void mouseExited(java.awt.event.MouseEvent evt) {
                if (button.isEnabled()) {
                    button.setBackground(backgroundColor);
                }
            }
        });
    }

    /**
     * 设置表格列的排序比较器
     */
    private void setupColumnComparators() {
        // 预约ID列 - 数字排序
        tableSorter.setComparator(0, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                try {
                    return Integer.compare(Integer.parseInt(o1), Integer.parseInt(o2));
                } catch (NumberFormatException e) {
                    return o1.compareTo(o2);
                }
            }
        });

        // 座位号列 - 自然排序
        tableSorter.setComparator(1, String.CASE_INSENSITIVE_ORDER);

        // 楼层列 - 数字排序
        tableSorter.setComparator(2, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                try {
                    return Integer.compare(Integer.parseInt(o1), Integer.parseInt(o2));
                } catch (NumberFormatException e) {
                    return o1.compareTo(o2);
                }
            }
        });

        // 预约日期列 - 日期排序
        tableSorter.setComparator(3, String.CASE_INSENSITIVE_ORDER);

        // 开始时间列 - 时间排序
        tableSorter.setComparator(4, String.CASE_INSENSITIVE_ORDER);

        // 结束时间列 - 时间排序
        tableSorter.setComparator(5, String.CASE_INSENSITIVE_ORDER);

        // 状态列 - 状态优先级排序
        tableSorter.setComparator(6, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return getStatusPriority(o1) - getStatusPriority(o2);
            }

            private int getStatusPriority(String status) {
                switch (status) {
                    case "有效":
                        return 1;
                    case "已完成":
                        return 2;
                    case "已取消":
                        return 3;
                    default:
                        return 999;
                }
            }
        });

        // 预约时间列 - 时间戳排序
        tableSorter.setComparator(7, String.CASE_INSENSITIVE_ORDER);
    }

}
